﻿using Microsoft.AspNetCore.Mvc.Filters;
using Prometheus;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Distributed_ResourceMonitor.ResourceMonitor
{
    [AttributeUsage(AttributeTargets.Method)]
    public class MonitorAttribute : ActionFilterAttribute
    {
        public string InterfaceName;
        public string ServiceName;
        private readonly Counter _requestCounter = null;
        private readonly Histogram _requestDuration = null;
        private readonly Gauge _requestInProgress = null;

        public MonitorAttribute(string serviceName, string interfaceName)
        {
            ServiceName = serviceName;
            InterfaceName = interfaceName;

            /// <summary>
            /// 1、创建接口计数器【监控接口调用总量】
            /// </summary>
            _requestCounter =
                Metrics.CreateCounter(
               $"{ServiceName}_{InterfaceName}_request_total",
               $"{ServiceName} 接口请求总量",
               new CounterConfiguration
               {
                   LabelNames = new[] { "controller", "action", "status_code" }
               });

            /// <summary>
            /// 1、创建图表器【监控接口响应时间】
            /// </summary>
            _requestDuration =
             Metrics.CreateHistogram(
                 $"{ServiceName}_{InterfaceName}_request_duration_seconds",
                  $"{ServiceName} 接口响应时间",
                 new HistogramConfiguration
                 {
                     LabelNames = new[] { "controller", "action", "status_code" },
                     Buckets = new[] { 0.01, 0.05, 0.1, 0.5, 1, 2, 5, 10 }  // 响应时间桶,秒为单位
                 });

            /// <summary>
            /// 1、创建Gauge【监控接口并发量】
            /// </summary>
            _requestInProgress =
              Metrics.CreateGauge(
                  $"{ServiceName}_{InterfaceName}_request_in_progress",
                   $"当前 {ServiceName} 正在处理并发量",
                  new GaugeConfiguration
                  {
                      LabelNames = new[] { "controller", "action" }
                  });
        }

        // 1、创建摘要Summary 监控器 Create

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="next"></param>
        /// <returns></returns>
        public override async Task OnActionExecutionAsync(ActionExecutingContext context,
                            ActionExecutionDelegate next)
        {
            var ControllerName = context.Controller.GetType().Name.Replace("Controller", "");
            var Action = context.ActionDescriptor.RouteValues["action"] ?? "";
            string statuscode = "200";

            // 1、开始并发计数
            var ProgressGauge = _requestInProgress.WithLabels(ControllerName, Action);
            ProgressGauge.Inc();

            // 2、开始时间
            var stopwatch = Stopwatch.StartNew();

            // 3、执行业务逻辑
            await next();

            // 结束时间
            var endtime = stopwatch.Elapsed.TotalSeconds;

            // 1、监控接口响应时间
            _requestDuration.WithLabels(ControllerName, Action, statuscode)
                            .Observe(endtime);

            // 2、使用接口计数器开始监控
            _requestCounter.WithLabels(ControllerName, Action, statuscode).Inc();

            // 3、并发减少
            ProgressGauge.Dec();

            // return base.OnActionExecutionAsync(context, next);
        }
    }
}
